<!DOCTYPE html>
<html>
<head>
<title>Physics Diagram of Reflection from a Sphere</title>
<style>
  body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background-color: #f9f9f9;
  }
  canvas {
    border: 1px solid #ddd;
    background-color: #fff;
  }
</style>
</head>
<body>
<canvas id="physicsCanvas" width="450" height="450"></canvas>
<script>
  const canvas = document.getElementById('physicsCanvas');
  const ctx = canvas.getContext('2d');

  // Style settings inspired by the image
  ctx.lineWidth = 2.5;
  ctx.strokeStyle = 'black';
  ctx.fillStyle = 'black';
  ctx.font = '22px sans-serif';
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';

  // Parameters for the drawing
  const cx = 225;
  const cy = 200;
  const sphereRadius = 80;
  const theta = 40 * Math.PI / 180; // Angle theta in radians, chosen to be illustrative

  // --- Drawing functions ---

  // Function to draw an arrowhead
  function drawArrowhead(ctx, fromX, fromY, toX, toY, headLength = 12) {
    const dx = toX - fromX;
    const dy = toY - fromY;
    const angle = Math.atan2(dy, dx);
    ctx.beginPath();
    ctx.moveTo(toX, toY);
    ctx.lineTo(toX - headLength * Math.cos(angle - Math.PI / 6), toY - headLength * Math.sin(angle - Math.PI / 6));
    ctx.moveTo(toX, toY);
    ctx.lineTo(toX - headLength * Math.cos(angle + Math.PI / 6), toY - headLength * Math.sin(angle + Math.PI / 6));
    ctx.stroke();
  }
  
  // --- Draw main elements ---

  // 1. Draw Z-axis
  ctx.beginPath();
  ctx.moveTo(cx, 50);
  ctx.lineTo(cx, cy + sphereRadius + 60);
  ctx.stroke();
  ctx.fillText('z', cx - 20, 60);

  // 2. Draw sphere
  ctx.beginPath();
  ctx.arc(cx, cy, sphereRadius, 0, 2 * Math.PI);
  ctx.stroke();
  ctx.fillText('O', cx - 20, cy + 5);
  ctx.textAlign = 'left';
  ctx.fillText('sphere', cx + sphereRadius + 15, cy + 10);
  ctx.textAlign = 'center';


  // 3. Calculate point of impact
  const impactX = cx + sphereRadius * Math.sin(theta);
  const impactY = cy - sphereRadius * Math.cos(theta);

  // 4. Draw dashed normal line (radius 'r')
  ctx.save();
  ctx.setLineDash([5, 5]);
  ctx.beginPath();
  ctx.moveTo(cx, cy);
  ctx.lineTo(impactX, impactY);
  ctx.stroke();
  ctx.restore();
  
  // 5. Draw incoming ray
  const rayLength = 70;
  const startIncomingX = impactX;
  const startIncomingY = impactY - rayLength;
  ctx.beginPath();
  ctx.moveTo(startIncomingX, startIncomingY);
  ctx.lineTo(impactX, impactY);
  ctx.stroke();
  drawArrowhead(ctx, startIncomingX, startIncomingY, impactX, impactY);

  // 6. Draw reflected ray
  // For an incident ray parallel to the y-axis, the reflected ray angle with the vertical is 2*theta.
  const reflectedAngle = 2 * theta;
  const endReflectedX = impactX + rayLength * Math.sin(reflectedAngle);
  const endReflectedY = impactY - rayLength * Math.cos(reflectedAngle);
  ctx.beginPath();
  ctx.moveTo(impactX, impactY);
  ctx.lineTo(endReflectedX, endReflectedY);
  ctx.stroke();
  drawArrowhead(ctx, impactX, impactY, endReflectedX, endReflectedY);

  // --- Draw labels ---

  // 7. Draw angle 'θ' arc and label
  const arcRadius = 35;
  ctx.beginPath();
  ctx.arc(cx, cy, arcRadius, -Math.PI / 2, -Math.PI / 2 + theta);
  ctx.stroke();
  const thetaLabelX = cx + (arcRadius + 18) * Math.sin(theta / 2);
  const thetaLabelY = cy - (arcRadius + 18) * Math.cos(theta / 2);
  ctx.fillText('θ', thetaLabelX, thetaLabelY);

  // 8. Draw label 'r'
  const rLabelX = cx + (sphereRadius / 1.8) * Math.sin(theta);
  const rLabelY = cy - (sphereRadius / 1.8) * Math.cos(theta);
  ctx.fillText('r', rLabelX + 10, rLabelY - 5);

  // 9. Draw Figure caption
  ctx.fillText('Fig. 1.26.', cx, cy + sphereRadius + 100);

</script>
</body>
</html>